package cn.iotab.iotkit.transport.mqtt.handler;

import cn.iotab.iotkit.transport.api.driver.TransportDriverService;
import cn.iotab.iotkit.transport.mqtt.MqttTransportContext;
import cn.iotab.iotkit.transport.mqtt.session.MqttSessionCtx;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttQoS;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractMqttMessageHandler<T extends MqttMessage> {

    private static final MqttQoS MAX_SUPPORTED_QOS_LVL = MqttQoS.AT_LEAST_ONCE;

    protected final MqttTransportContext context;
    protected final TransportDriverService transportDriverService;

    protected final String sessionId;
    protected final MqttSessionCtx deviceSessionCtx;

    public AbstractMqttMessageHandler(MqttTransportContext context, MqttSessionCtx deviceSessionCtx) {
        this.context = context;
        this.transportDriverService = context.getTransportDriverService();

        this.deviceSessionCtx = deviceSessionCtx;
        this.sessionId = deviceSessionCtx.getSessionId();
    }


    public abstract void process(ChannelHandlerContext ctx, T msg);

    protected boolean checkConnected(ChannelHandlerContext ctx, MqttMessage msg) {
        if (deviceSessionCtx.isConnected()) {
            return true;
        } else {
            log.info("[{}] Closing current session due to invalid msg order: {}", sessionId, msg);
            ctx.close();
            return false;
        }
    }


    protected static int getMinSupportedQos(MqttQoS reqQoS) {
        return Math.min(reqQoS.value(), MAX_SUPPORTED_QOS_LVL.value());
    }
}
